<?php
/**
 * This file is part of DomLocker.
 * 
 * DomLocker is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * DomLocker is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with DomLocker.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * @link http://inditel.ee/
 * @copyright 2007-2009 Inditel Meedia OÜ
 * @author Oliver Leisalu <oliver@inditel.ee>
 */

/**
* Needed constants
* DOM_CACHE_TYPE - possible values
* 1 - XCache driver
* other - File driver
* 
* DOM_CACHE_LIFE - default cache time in seconds.
* 
* All cache drivers must be held in this file. (Not external - caching is used prior to autoload, so no external files will be loaded)
*
* @author Oliver Leisalu, Inditel Meedia OÜ
* @package DomCache
*/
class DomCache {
    
	/**
	* @var DomCacheDriver Cache driver
	*/
	private static $driver;

    public static function init() {
		
    	if( DOM_CACHE_TYPE === 1 && function_exists('xcache_get') === true ) {
			self::setCacheDriver( new DomCacheDriver_XCache() );
			trace('DomCache is working on <strong>XCACHE</strong> mode', 'Dom');
		
		} else {
			self::setCacheDriver( new DomCacheDriver_File() );
			trace('DomCache is working on <strong>FILE</strong> mode', 'Dom');
		}
		
		self::$driver->init();
	}
	
	/**
	 * @param DomCacheDriver $driver
	 */
	public static function setCacheDriver( DomCacheDriver $driver ) {
		self::$driver = $driver;
	}
	/**
	 * 
	 * @return DomCacheDriver
	 */
	public static function getCacheDriver() {
		return self::$driver;
	}
	
	/**
	* @param String $key
	* @param Mixed $value
	* @param Int $time Time in seconds.
	*/
	public static function cache( $key, $value, $time = DOM_CACHE_LIFE ) {
		return self::$driver->cache( $key, $value, $time );
	}
	/**
	 * @param String $key
	 * @return Mixed
	 */
	public static function get( $key ){
		return self::$driver->get( $key);
	}
	/**
	 * Checks if data is cached
	 * @param String $key
	 * @return Boolean
	 */
	public static function isCached( $key ) {
		return self::$driver->isCached( $key);
	}
	/**
	 * Deletes cache
	 * @param String $key
	 */
	public static function remove( $key ) {
		return self::$driver->remove( $key);
	}
	/**
	 * Cleares all cache
	 */
	public static function clearAllCache() {
		return self::$driver->clearAllCache( $key);
	}
}

/**
* @author Oliver Leisalu, Inditel Meedia OÜ
* @package DomCache
*/
interface DomCacheDriver {
	
	/**
	 * Initializes cache. (Do what you need to setup driver)
	 */
	public function init();
	/**
	* @param String $key
	* @param Mixed $value
	* @param Int $time Time in seconds.
	*/
	public function cache( $key, $value, $time = DOM_CACHE_LIFE );
	/**
	 * @param String $key
	 * @return Mixed
	 */
	public function get( $key );
	/**
	 * Checks if data is cached
	 * @param String $key
	 * @return Boolean
	 */
	public function isCached( $key );
	/**
	 * Deletes cache
	 * @param String $key
	 */
	public function remove( $key );
	/**
	 * Cleares all cache
	 */
	public function clearAllCache();
	
}

/**
* @author Oliver Leisalu, Inditel Meedia OÜ
* @package DomCache
*/
class DomCacheDriver_File implements DomCacheDriver {
	
	private $dataCache = array();
	
	public function init() {
		if( is_dir( DOM_CACHE_PATH.'/DomCache/') === false ) {
			mkdir( DOM_CACHE_PATH.'/DomCache/' );
		}
	}
	
	public function cache( $key, $value, $time = DOM_CACHE_LIFE ) {
		$serialized = is_array($value) or is_object($value);
		if( $serialized === true ) {
			$value = serialize($value);
		}
		$fileName = self::getCacheFileName($key);
		file_put_contents( $fileName, (time() + (int)$time).'|'.(int)$serialized.'|'.$value );
		@chmod( $fileName, 0777);
	}

	public function get( $key ){

		list($cacheExpires,$serialized,$data) = self::loadCacheFile( $key );
		// required file containts this variable $cacheExpires
		if( (int)$cacheExpires > time() ) {
			if( $serialized == true ) {
				return unserialize( $data );
			} else {
				return $data;
			}
		} else {
			self::remove( $key );
			return NULL;
		}

	}

	public function isCached( $key ) {
		$data = self::loadCacheFile( $key );
		return $data[0] > time();
	}

	public function remove( $key ) {
		@unlink(self::getCacheFileName( $key ));
	}

	public function clearAllCache() {
		foreach( glob(DOM_CACHE_PATH.'/DomCache/c_*') as $path ) {
			@unlink($path);
		}
	}

	
	
	/**
	 * @param String $key cache key
	 * @return String
	 */
	private function getCacheFileName( $key ) {
		return DOM_CACHE_PATH.'/DomCache/c_'.$key.'.txt';
	}
	/**
	 * Loads cache file contents
	 * @param String $key
	 * @return Array
	 * Array keys
	 * 0 - cache expire time
	 * 1 - is serialized
	 * 2 - data
	 */
	private function loadCacheFile( $key ) {
		return explode('|',@file_get_contents(  self::getCacheFileName( $key ) ), 3);
	}
	
	

}

/**
* @author Oliver Leisalu, Inditel Meedia OÜ
* @package DomCache
*/
class DomCacheDriver_XCache implements DomCacheDriver {

	public function init() {
	
	}
	
	public function cache( $key, $value, $time = DOM_CACHE_LIFE ) {
		return xcache_set( DOM_RUN_ID.$key, $value, $time );
	}
	
	public function get( $key ){
		return xcache_get(DOM_RUN_ID.$key);
	}

	public function isCached( $key ) {
		return xcache_isset(DOM_RUN_ID.$key);
	}
	
	public function remove( $key ) {
		xcache_unset( DOM_RUN_ID.$key );
	}
	
	public function clearAllCache() {
		xcache_clear_cache( XC_TYPE_VAR, 0);
		xcache_clear_cache( XC_TYPE_PHP, 0);
	}

}
?>